﻿namespace MtmDeepCopy
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    using System.Xml;

    public delegate void CallbackDelegate(int value, string currentOperation);

    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class ProgressDlg : Window
    {
        private ProgressViewModel _vm;
        private ActionExec _currentAction;
        private int _currentActionProgress;

        public ProgressDlg()
        {
            InitializeComponent();

            _vm = new ProgressViewModel();
            DataContext = _vm;
            cmdClose.Visibility = Visibility.Hidden;
        }

        public bool? DoProgress(Window parentWindow, string title,  Dictionary<string, object> sharedVariables, List<IAction> lst)
        {
            _vm.SetActions(lst);
            _vm.SharedVariables = sharedVariables;
            Owner = parentWindow;
            Title = title;
            ShowDialog();

            return true;
        }

        public void UpdateStatus(int value, string currentOperation)
        {
            _currentActionProgress = value;
            if (value == int.MaxValue)
            {
                cmdClose.Visibility = Visibility.Visible;

                if (_vm.Actions.Count(a  => a.Status != ActionExecStatus.Done) == 0)
                {
                    Close();
                }

                value = (int)progressTotal.Maximum;
            }

            progressTotal.Value = value;
            txtCurrentActivity.Text = currentOperation;
            txtCurrentDetail.Text = string.Empty;
           
          ////  dataGrid1.DataContext = _vm.Actions;
          //  _vm.NotifyPropertyChanged("Actions");
          //  var bindingExpression = dataGrid1.GetBindingExpression(DataGrid.ItemsSourceProperty);
          //  bindingExpression.UpdateTarget();
        }

        public void UpdateActionStatus(double value, string currentOperation)
        {
            progressTotal.Value = _currentActionProgress + value;
            txtCurrentDetail.Text = currentOperation;

            _currentAction.Message = currentOperation;
            _currentAction.Log = _currentAction.Log + "/r/n" + currentOperation;

            ////  dataGrid1.DataContext = _vm.Actions;
            //  _vm.NotifyPropertyChanged("Actions");
            //  var bindingExpression = dataGrid1.GetBindingExpression(DataGrid.ItemsSourceProperty);
            //  bindingExpression.UpdateTarget();
        }

        public void DispatchUpdateActionStatus(double value, string currentOperation)
        {
            ActionNotifyCallbackDelegate detailedCallback = new ActionNotifyCallbackDelegate(UpdateActionStatus);
            Dispatcher.Invoke(detailedCallback, System.Windows.Threading.DispatcherPriority.Background, new object[] { value, currentOperation });
        }

        public void UpdateNodes(string guid, int id)
        {
            XmlDocument doc = _vm.SharedVariables["TargetTestSuites"] as XmlDocument;
            XmlNode node = doc.SelectSingleNode(@"//TestSuite[@Guid = '" + guid + "']");

            XmlAttribute aSuiteId = node.OwnerDocument.CreateAttribute("SuiteId");
            aSuiteId.Value = id.ToString();
            node.Attributes.Append(aSuiteId);
        }

        public void DispatchUpdateNodes(string guid, int id)
        {
            UpdateNodesDelegate nodeCallback = new UpdateNodesDelegate(UpdateNodes);
            Dispatcher.Invoke(nodeCallback, System.Windows.Threading.DispatcherPriority.Background, new object[] { guid, id });
        }

        public void ExecuteActions()
        {
            int i = 0;
            CallbackDelegate callback = new CallbackDelegate(UpdateStatus);
            ActionNotifyCallbackDelegate detailedCallback = new ActionNotifyCallbackDelegate(DispatchUpdateActionStatus);
            UpdateNodesDelegate updateNodeCallback = new UpdateNodesDelegate(DispatchUpdateNodes);

            foreach (ActionExec a in _vm.Actions)
            {
                _currentAction = a;

                a.Status = ActionExecStatus.Runing;
                Dispatcher.Invoke(callback, System.Windows.Threading.DispatcherPriority.Background, new object[] { i, a.Title });

                bool result = a.theAction.Execute(ref _vm.SharedVariables, detailedCallback, updateNodeCallback);
                a.Status = result ? ActionExecStatus.Done : ActionExecStatus.Failed;

                i++;
                Dispatcher.Invoke(callback, System.Windows.Threading.DispatcherPriority.Background, new object[] { i, a.Title });
            }

            Dispatcher.Invoke(callback, System.Windows.Threading.DispatcherPriority.Background, new object[] { int.MaxValue, "Done" });
        }

        private void cmdClose_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            progressTotal.Minimum = 0;
            progressTotal.Maximum = _vm.Actions.Count();
            progressTotal.Value = 0;

            txtCurrentActivity.Text = "Start working ";
            Thread workerThread = new Thread(delegate() { ExecuteActions(); });
            
            workerThread.Start();
        }
    }  
}
